package savi.classes;

import java.util.List;

import javax.jdo.PersistenceManager;

import savi.jdo.Event;
import savi.jdo.Student;
import savi.jdo.StudentModule;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class Accounts {

	private static UserService userService;
	private static Accounts instance = null;

	private Accounts() {
		userService = UserServiceFactory.getUserService();
	}

	private PersistenceManager getPM() {
		return Datastore.getPersistanceManager();
	}

	public static Accounts inst() {
		if (instance == null)
			instance = new Accounts();

		return instance;
	}

	private int getNewModuleSerialNo() {
		PersistenceManager pm = null;
		int result;

		String query = "SELECT FROM " + StudentModule.class.getName();

		try {
			pm = getPM();

			@SuppressWarnings("unchecked")
			List<StudentModule> modules = (List<StudentModule>) pm.newQuery(
					query).execute();

			if (modules.isEmpty())
				result = 0;
			else
				result = Integer.parseInt(modules.get(modules.size() - 1)
						.getSerialNo().replace("c", "")) + 1;
		} finally {
			if (pm != null)
				pm.close();
		}

		return result;
	}

	public boolean isLoggedOn() {
		return userService.getCurrentUser() != null;
	}

	public String getLoginPage(String redirectPage) {
		User user = userService.getCurrentUser();

		if (user != null)
			return redirectPage;
		else
			return userService.createLoginURL(redirectPage);
	}

	public String getLogoutPage(String redirectPage) {
		return userService.createLogoutURL(redirectPage);
	}

	public User getUser() {
		return userService.getCurrentUser();
	}

	public String getUserName() {
		return userService.getCurrentUser().getNickname();
	}

	public boolean modulesRetrieved() {
		PersistenceManager pm = null;
		boolean result;

		String query1 = "SELECT FROM " + Student.class.getName()
				+ " WHERE googleID=='" + getUserName() + "'";
		String query2 = "SELECT FROM " + StudentModule.class.getName()
				+ " WHERE googleID=='" + getUserName() + "'";

		try {
			pm = getPM();

			@SuppressWarnings("unchecked")
			List<Student> students = (List<Student>) getPM().newQuery(query1)
					.execute();

			@SuppressWarnings("unchecked")
			List<String> modules = (List<String>) getPM().newQuery(query2)
					.execute();

			result = !(students.isEmpty() || modules.isEmpty());
		} finally {
			if (pm != null)
				pm.close();
		}
		return result;
	}

	private Student doesUserExist() {
		PersistenceManager pm = null;
		Student result;

		String query = "SELECT FROM " + Student.class.getName()
				+ " WHERE googleID =='" + getUserName() + "'";

		try {
			pm = getPM();

			@SuppressWarnings("unchecked")
			List<Student> studentList = (List<Student>) pm.newQuery(query)
					.execute();

			result = !studentList.isEmpty() ? studentList.get(0) : null;
		} finally {
			if (pm != null)
				pm.close();
		}
		return result;
	}

	public String getUserModuleList() {
		PersistenceManager pm = null;
		String xmlResult = "<MODULES>";

		String query = "SELECT FROM " + StudentModule.class.getName()
				+ " WHERE googleID == '" + getUserName() + "'";

		try {
			pm = getPM();

			Student student = doesUserExist();
			if (student != null) {
				@SuppressWarnings("unchecked")
				List<StudentModule> modules = (List<StudentModule>) pm
						.newQuery(query).execute();

				for (StudentModule m : modules) {
					xmlResult += "<ID>" + m.getmoduleID() + "</ID>";
				}
			} else {
				Student newStudent = new Student(getUserName(), getUserName(),
						userService.getCurrentUser().getEmail());
				pm.makePersistent(newStudent);

			}
		} finally {
			if (pm != null)
				pm.close();
		}
		xmlResult += "</MODULES>";
		return xmlResult;
	}

	public void addUserModule(String moduleId) {
		PersistenceManager pm = null;
		StudentModule studentModule = new StudentModule(getUserName(),
				moduleId, "c" + getNewModuleSerialNo());
		String query = "SELECT FROM " + StudentModule.class.getName()
				+ " WHERE googleID=='" + getUserName() + "'";

		try {
			Student student = doesUserExist();
			pm = getPM();

			if (student == null) {
				Student newStudent = new Student(getUserName(), getUserName(),
						userService.getCurrentUser().getEmail());

				pm.makePersistent(newStudent);
				pm.makePersistent(studentModule);
			} else {
				@SuppressWarnings("unchecked")
				List<StudentModule> modules = (List<StudentModule>) pm
						.newQuery(query).execute();

				boolean modExists = false;
				for (StudentModule m : modules) {
					if (m.getmoduleID().compareTo(moduleId) == 0) {
						modExists = true;
						break;
					}
				}

				if (!modExists) {
					pm.makePersistent(studentModule);
				}
			}
		} finally {
			if (pm != null)
				pm.close();
		}
	}

	public void deleteUserModule(String moduleId) {
		PersistenceManager pm = null;

		String query = "SELECT FROM " + StudentModule.class.getName()
				+ " WHERE googleID == '" + getUserName() + "'";

		try {
			pm = getPM();

			@SuppressWarnings("unchecked")
			List<StudentModule> modules = (List<StudentModule>) pm.newQuery(
					query).execute();

			for (StudentModule m : modules) {
				if (m.getmoduleID().compareTo(moduleId) == 0) {
					pm.deletePersistent(m);
					break;
				}
			}
		} finally {
			if (pm != null)
				pm.close();
		}
	}

	public void addUserModuleList(List<String> moduleList) {
		PersistenceManager pm = null;
		Student student = doesUserExist();

		try {
			pm = getPM();

			if (student == null) {
				student = new Student(getUserName(), getUserName(), userService
						.getCurrentUser().getEmail());
				pm.makePersistent(student);

			}

			for (String m : moduleList) {
				StudentModule studentModule = new StudentModule(getUserName(),
						m, "c" + getNewModuleSerialNo());
				pm.makePersistent(studentModule);
			}
		} finally {
			if (pm != null)
				pm.close();
		}
	}
}
